package com.adcc.soundalarm.config.regular;

import com.adcc.soundalarm.common.Constant;
import com.adcc.soundalarm.common.Log;
import com.adcc.soundalarm.manager.RegularConfigManager;
import com.adcc.utility.xml.*;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.*;
import java.util.*;

/**
 * Created by zhangdawei on 2017/3/21.
 * 告警规则配置管理类
 */
public class RegularXMLConfiguration {

    // AMQS 状态告警配置
    private String amqs;

    // MQ 状态告警配置
    private String mqState;

    // GW 状态告警配置
    private String gw;

    // 用户自动同步
    private String autoSync;

    // BGS 用户状态告警配置
    private List<String> content;

    // 用户上线列表管理
    private List<String> onlineUserList;

    // 用户下线列表管理
    private List<String> offlineuserList;


    //单例模式
    private RegularXMLConfiguration(){}

    /**
     * 静态内部类
     */
    private static class LazyHolder{
        private static final RegularXMLConfiguration INSTANCE = new RegularXMLConfiguration();
    }

    /**
     * 单例方法
     * */
    public synchronized static RegularXMLConfiguration getInstance() {
        return LazyHolder.INSTANCE;
    }

    /**
     * 配置加载
     */
    public void init(){
        load();
    }


    public Document loadXMLFile(String path) throws Exception {
        BufferedReader br = null;
        Document document = null;
        try {
            // SAXReader
            SAXReader saxReader = new SAXReader();
            br = new BufferedReader(new InputStreamReader(new FileInputStream(path),"UTF-8"));
            document  = saxReader.read(br);
        } catch (IOException ex) {
            Log.error("loadXMLFile  error", ex);
        }finally {
            try {
                if(br != null) {
                    br.close();
                }
            } catch (IOException ex) {
                Log.error("close io error", ex);
            }
        }
        return document;
    }


    public void load(){
        String path = System.getProperty("user.dir")+ File.separator+"conf"+File.separator+"regular.xml" ;
        try{
            Document document = loadXMLFile(path);
            if(document!=null ){
                Element root = document.getRootElement();
                if(root!=null){
                    Element elementAMQS = root.element(Constant.XML_ELEMENT_AMQS_NAME);
                    if(elementAMQS!=null){
                        this.setAmqs(elementAMQS.getText());
                    }
                    Element elementMQ = root.element(Constant.XML_ELEMENT_MQ_NAME);
                    if(elementMQ!=null){
                        this.setMqState(elementMQ.getText());
                    }
                    Element elementGW = root.element(Constant.XML_ELEMENT_GW_NAME);
                    if(elementGW!=null){
                        this.setGw(elementGW.getText());
                    }
                    Element elementAutoSync= root.element(Constant.XML_ELEMENT__USER_AUTO_SYNC);
                    if(elementAutoSync != null){
                        this.setAutoSync(elementAutoSync.getText());
                    }
                    Element elementLog = root.element(Constant.XML_ELEMENT_LOG_NAME);
                    if(elementLog!=null){
                        List<String> logs = Lists.newArrayList();
                        for (Iterator<Element> iterator = elementLog.elementIterator();iterator.hasNext();){
                            Element element = iterator.next();
                            logs.add(element.getText());
                        }
                        this.setContent(logs);
                    }
                    Element offlineUsers = root.element(Constant.XML_ELEMENT_USER_OFFLINE_NAME);
                    if(offlineUsers !=null ){
                        List<String> offUsers= Lists.newArrayList();
                        for (Iterator<Element> iterator = offlineUsers.elementIterator();iterator.hasNext();){
                            Element element = iterator.next();
                            if(element!=null){
                                offUsers.add(element.attribute(Constant.XML_ELEMENT_USER_ATTRIBUTE).getValue());
                            }
                        }
                        this.setOfflineuserList(offUsers);
                    }
                    Element onlineUsers = root.element(Constant.XML_ELEMENT_USER_ONLINE_NAME);
                    if(onlineUsers !=null ){
                        List<String> onUsers= Lists.newArrayList();
                        for (Iterator<Element> iterator = onlineUsers.elementIterator();iterator.hasNext();){
                            Element element = iterator.next();
                            if(element!=null){
                                onUsers.add(element.attribute(Constant.XML_ELEMENT_USER_ATTRIBUTE).getValue());
                            }
                        }
                        this.setOnlineUserList(onUsers);
                    }
                }
            }
        }catch (Exception e){
            Log.error("load method error!", e);
        }
    }

    /**
     * 规则配置存储
     * @param configManager
     * @return
     */
    public boolean saveConfigToXMLFile(RegularConfigManager configManager){
        boolean result = false;
        String path = System.getProperty("user.dir")+File.separator+"conf"+File.separator+"regular.xml";
        XMLWriter writer = null;
        try {
            Document docNew = createXML(configManager);
            if(docNew != null){
                writer = new XMLWriter(new FileOutputStream(path), OutputFormat.createPrettyPrint());
                writer.write(docNew);
            }
            result = true;
        } catch (Exception ex) {
            Log.error("saveConfigToXMLFile() error", ex);
        }finally {
            try {
                if (writer!=null){
                    writer.close();
                }
            } catch (IOException e) {
                Log.error("saveConfigToXMLFile close error", e);
            }
        }
        return result;
    }

    public boolean syncUser(List<String> users){
        boolean result = false;
        String path = System.getProperty("user.dir")+File.separator+"conf"+File.separator+"regular.xml";
        XMLWriter writer = null;
        try {
            Document doc = loadXMLFile(path);
            if(doc != null){
                doc.setXMLEncoding(Constant.DEFAULT_CHARSET);
                Element rootElement =  doc.getRootElement() ==null ? doc.addElement(Constant.XML_ROOT_NAME):doc.getRootElement();
                Element onlineUserListElement = rootElement.element(Constant.XML_ELEMENT_USER_ONLINE_NAME);
                Element offlineUserListElement = rootElement.element(Constant.XML_ELEMENT_USER_OFFLINE_NAME);
                List<String> list = Lists.newArrayList();
                list.addAll(users);
                if(onlineUserListElement!=null){
                    for (Iterator<Element> iterator = onlineUserListElement.elementIterator();iterator.hasNext();){
                        Element element = iterator.next();
                        boolean equal = false;
                        for (String str:users){
                            if(str.equals(element.attribute(Constant.XML_ELEMENT_USER_ATTRIBUTE).getValue())) {
                                list.remove(str);
                                equal = true;
                            }
                        }
                        if(!equal){
                            onlineUserListElement.remove(element);
                        }
                    }
                }
                if(offlineUserListElement!=null){
                    for (Iterator<Element> iterator = offlineUserListElement.elementIterator();iterator.hasNext();){
                        Element element = iterator.next();
                        boolean equal = false;
                        for (String str:users){
                            if(str.equals(element.attribute(Constant.XML_ELEMENT_USER_ATTRIBUTE).getValue())) {
                                list.remove(str);
                                equal = true;
                            }
                        }
                        if(!equal){
                            offlineUserListElement.remove(element);
                        }
                    }
                }
                if(list.size()>0){
                    for (String str:list){
                        Element element = offlineUserListElement.addElement(Constant.XML_ELEMENT_USER_NAME);
                        element.addAttribute(Constant.XML_ELEMENT_USER_ATTRIBUTE,str);
                    }
                }
                writer = new XMLWriter(new FileOutputStream(path), OutputFormat.createPrettyPrint());
                writer.write(doc);
            }
            result = true;
        } catch (Exception ex) {
            Log.error("syncUser() error", ex);
        }finally {
            try {
                if (writer!=null){
                    writer.close();
                }
            } catch (IOException e) {
                Log.error("syncUser close error", e);
            }
        }
        return result;
    }

    private Document createXML(RegularConfigManager configManager){
        // 实例化Document4J对象
        Document document = null;
        try{
            ADCCXML adccxml  = ADCCXMLFactory.getInstance().createADCCXML();
            adccxml.getRoot().put("version","1");
            SuperNode AMQSuperNode = new SuperNode(Constant.XML_ELEMENT_AMQS_NAME);
            SuperNode MQSuperNode = new SuperNode(Constant.XML_ELEMENT_MQ_NAME);
            SuperNode GWSuperNode = new SuperNode(Constant.XML_ELEMENT_GW_NAME);
            SuperNode autoSuperNode = new SuperNode(Constant.XML_ELEMENT__USER_AUTO_SYNC);
            SuperNode onlineSuperNode = new SuperNode(Constant.XML_ELEMENT_USER_ONLINE_NAME);
            SuperNode logsSuperNode = new SuperNode(Constant.XML_ELEMENT_LOG_NAME);
            SuperNode offlineSuperNode = new SuperNode(Constant.XML_ELEMENT_USER_OFFLINE_NAME);
            if(!Strings.isNullOrEmpty(configManager.getAmqs())){
                AMQSuperNode.setText(configManager.getAmqs());
                adccxml.addSuperNode(AMQSuperNode);
            }
            if (!Strings.isNullOrEmpty(configManager.getMqState())) {
                MQSuperNode.setText(configManager.getMqState());
                adccxml.addSuperNode(MQSuperNode);
            }
            if (!Strings.isNullOrEmpty(configManager.getGw())) {
                GWSuperNode.setText(configManager.getGw());
                adccxml.addSuperNode(GWSuperNode);
            }
            if (!Strings.isNullOrEmpty(configManager.getAutoSysnc())) {
                autoSuperNode.setText(configManager.getAutoSysnc());
                adccxml.addSuperNode(autoSuperNode);
            }
            if (configManager.getLog() != null) {
                if (configManager.getLog().size() > 0) {
                    for (String log : configManager.getLog()) {
                        Node content = new Node(Constant.XML_ELEMENT_LOG_CONTENT_NAME);
                        content.setText(log);
                        logsSuperNode.getNodeList().add(content);
                    }
                    adccxml.addSuperNode(logsSuperNode);
                }
            }
            if (this.getOnlineUserList() != null) {
                if(this.getOnlineUserList().size()>0){
                    for(String name :this.getOnlineUserList()){
                        Node user = new Node(Constant.XML_ELEMENT_USER_NAME);
                        user.getAttributes().put(Constant.XML_ELEMENT_USER_ATTRIBUTE, name);
                        onlineSuperNode.getNodeList().add(user);
                    }
                    adccxml.addSuperNode(onlineSuperNode);
                }
            }
            if (this.getOfflineuserList() != null) {
                if(this.getOfflineuserList().size()>0){
                    for(String name :this.getOfflineuserList()){
                        Node user = new Node(Constant.XML_ELEMENT_USER_NAME);
                        user.getAttributes().put(Constant.XML_ELEMENT_USER_ATTRIBUTE, name);
                        offlineSuperNode.getNodeList().add(user);
                    }
                    adccxml.addSuperNode(offlineSuperNode);
                }
            }
            document = adccxml.createXML();
            return document;
        }catch (Exception ex){
            Log.error("createXML() error"+ex);
            return null;
        }

        // 添加Root节点
//        Element eltRoot = document.addElement(Constant.XML_ROOT_NAME);
//        if(!Strings.isNullOrEmpty(configManager.getAmqs())){
//            Element element = eltRoot.addElement(Constant.XML_ELEMENT_AMQS_NAME);
//            element.setText(configManager.getAmqs());
//        }
//        if(!Strings.isNullOrEmpty(configManager.getMqState())){
//            Element element = eltRoot.addElement(Constant.XML_ELEMENT_MQ_NAME);
//            element.setText(configManager.getMqState());
//        }
//        if(!Strings.isNullOrEmpty(configManager.getGw())){
//            Element element = eltRoot.addElement(Constant.XML_ELEMENT_GW_NAME);
//            element.setText(configManager.getGw());
//        }
//        if(!Strings.isNullOrEmpty(configManager.getAutoSysnc())){
//            Element element = eltRoot.addElement(Constant.XML_ELEMENT__USER_AUTO_SYNC);
//            element.setText(configManager.getAutoSysnc());
//        }
//        if(configManager.getLog()!=null){
//            Element element = eltRoot.addElement(Constant.XML_ELEMENT_LOG_NAME);
//            if(configManager.getLog().size() > 0){
//                for (String log : configManager.getLog()){
//                    Element logEle = element.addElement(Constant.XML_ELEMENT_LOG_CONTENT_NAME);
//                    logEle.setText(log);
//                }
//            }
//        }
//        if(this.getOnlineUserList()!=null){
//            Element element = eltRoot.addElement(Constant.XML_ELEMENT_USER_ONLINE_NAME);
//            addXMLNodeToUsers(getOnlineUserList(),element);
//        }
//        if(getOfflineuserList()!=null){
//            Element element = eltRoot.addElement(Constant.XML_ELEMENT_USER_OFFLINE_NAME);
//            addXMLNodeToUsers(getOfflineuserList(),element);
//        }
//        return document;
    }

    private void addXMLNodeToUsers(List <String> list,Element element){
        if(list.size()>0){
            for(String name :list){
                Element subEle = element.addElement(Constant.XML_ELEMENT_USER_NAME);
                subEle.addAttribute(Constant.XML_ELEMENT_USER_ATTRIBUTE,name);
            }
        }
    }

    public void sort(List<String> list){
        Collections.sort(list);
    }

    public String getAmqs() {
        return amqs;
    }

    public void setAmqs(String amqs) {
        this.amqs = amqs;
    }

    public String getMqState() {
        return mqState;
    }

    public void setMqState(String mqState) {
        this.mqState = mqState;
    }

    public String getGw() {
        return gw;
    }

    public void setGw(String gw) {
        this.gw = gw;
    }

    public String getAutoSync() {
        return autoSync;
    }

    public void setAutoSync(String autoSync) {
        this.autoSync = autoSync;
    }

    public List<String> getContent() {
        return content;
    }

    public void setContent(List<String> content) {
        this.content = content;
    }

    public List<String> getOfflineuserList() {
        return offlineuserList;
    }

    public void setOfflineuserList(List<String> offlineuserList) {
        this.offlineuserList = offlineuserList;
    }

    public List<String> getOnlineUserList() {
        return onlineUserList;
    }

    public void setOnlineUserList(List<String> onlineUserList) {
        this.onlineUserList = onlineUserList;
    }
}
